package com.meisupic.copyright.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyun.oss.model.PutObjectResult;
import com.meisupic.copyright.domain.bo.ImageInfo;
import com.meisupic.copyright.domain.vo.OssPostPolicyVo;
import com.meisupic.copyright.exception.BizException;
import com.meisupic.copyright.service.IOssService;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Date;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * creation wuxun
 *
 * @version V1.0
 * @Description: TODO
 * @date 2018/1/20 11:07
 */
@Service
public class OssServiceImpl implements IOssService {

  private OSS ossClient;

  @Value("${oss.accessKeyId}")
  private String accessKeyId;

  @Value("${oss.accessKeySecret}")
  private String accessKeySecret;

  @Value("${oss.bucketName}")
  private String bucketName;

  @Value("${oss.endpoint}")
  private String endpoint;

  private Logger logger = LoggerFactory.getLogger(this.getClass());

  @PostConstruct
  public void initOssClient() {
    logger.info("-----------------oss init --------------");
    this.ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  }

  @PreDestroy
  public void shutDownOssClient() {
    ossClient.shutdown();
    logger.info("-----------------oss shut down --------------");
  }

  /**
   * 文件上传
   */
  public void putObject(String key, File file) {
    try {
      PutObjectResult result = ossClient.putObject(bucketName, key, file);
      logger.info("上传到oss结果：{}", result.getETag());
    } catch (OSSException e) {
      logger.error("上传文件失败" + e.getMessage(), e);
      throw new BizException("上传文件到oss服务器错误，请稍后重试");
    } catch (ClientException e) {
      logger.error("上传文件失败" + e.getMessage(), e);
      throw new BizException("上传文件到oss服务器错误，请稍后重试");
    }
  }

  /**
   * 文件上传
   */
  public void putObject(String key, byte[] bytes) {
    ObjectMetadata meta = new ObjectMetadata();
    meta.setContentType("image/jpeg");
    ossClient.putObject(bucketName, key, new ByteArrayInputStream(bytes), meta);
  }

  /**
   * 删除文件对象
   */
  @Override
  public void deleteObject(String key) {
    try {
      ossClient.deleteObject(bucketName, key);
    } catch (OSSException e) {
      logger.error("删除文件对象失败", e);
    } catch (ClientException e) {
      logger.error("删除文件对象失败", e);
    }
  }


  @Override
  public OssPostPolicyVo getPostPolicy(String dir) {
    OssPostPolicyVo certOssPostPolicyVo = null;
    try {
      String host = "http://" + bucketName + "." + "oss-cn-beijing.aliyuncs.com";
      long expireTime = 300;
      long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
      Date expiration = new Date(expireEndTime);
      PolicyConditions policyConds = new PolicyConditions();
      policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
      policyConds
          .addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

      String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
      byte[] binaryData = postPolicy.getBytes("utf-8");
      String encodedPolicy = BinaryUtil.toBase64String(binaryData);
      String postSignature = ossClient.calculatePostSignature(postPolicy);
      certOssPostPolicyVo = new OssPostPolicyVo(dir, host, encodedPolicy, postSignature,
          expireEndTime, accessKeyId);
    } catch (UnsupportedEncodingException e) {
      logger.error("转码错误{}" + e.getMessage());
      throw new BizException("转码错误！");
    }
    return certOssPostPolicyVo;
  }

  @Override
  public void genThumbnail(String key) {
    String style = "image/info";
    GetObjectRequest request = new GetObjectRequest(bucketName, key);
    request.setProcess(style);
    OSSObject imageInfo = ossClient.getObject(request);
    imageInfo.getObjectContent();
    try {
      String imageInfoString = IOUtils.toString(imageInfo.getObjectContent());
      JSONObject imageInfoJson = JSON.parseObject(imageInfoString);
      String imageHeightValue = imageInfoJson.getString("ImageHeight");
      String imageWidthValue = imageInfoJson.getString("ImageWidth");
      int imageHeight = JSON.parseObject(imageHeightValue).getIntValue("value");
      int imageWidth = JSON.parseObject(imageWidthValue).getIntValue("value");

      style = "style/large_style_w";
      if (imageHeight > imageWidth) {
        style = "style/large_style_h";
      }
      request = new GetObjectRequest(bucketName, key);
      request.setProcess(style);
      OSSObject large_thumbnail = ossClient.getObject(request);
      String large_thumbnail_key = key + "_large";
      ossClient.putObject(bucketName, large_thumbnail_key, large_thumbnail.getObjectContent());

      style = "style/huge_style_w";
      if (imageHeight > imageWidth) {
        style = "style/huge_style_h";
      }
      request = new GetObjectRequest(bucketName, key);
      request.setProcess(style);
      OSSObject huge_thumbnail = ossClient.getObject(request);
      String huge_thumbnail_key = key + "_huge";
      ossClient.putObject(bucketName, huge_thumbnail_key, huge_thumbnail.getObjectContent());

      style = "style/max_style_w";
      if (imageHeight > imageWidth) {
        style = "style/max_style_h";

      }
      request = new GetObjectRequest(bucketName, key);
      request.setProcess(style);
      OSSObject max_thumbnail = ossClient.getObject(request);
      String max_thumbnail_key = key + "_max";
      ossClient.putObject(bucketName, max_thumbnail_key, max_thumbnail.getObjectContent());


    } catch (IOException e) {
      logger.error("生成缩略图读取图片信息出错", e);

    }
  }


  public ImageInfo getImageInfo(String key) {
    String style = "image/info";
    GetObjectRequest request = new GetObjectRequest(bucketName, key);
    request.setProcess(style);
    OSSObject imageInfo = ossClient.getObject(request);
    try {
      String imageInfoString = IOUtils.toString(imageInfo.getObjectContent());
      JSONObject imageInfoJson = JSON.parseObject(imageInfoString);
      String imageHeightValue = imageInfoJson.getString("ImageHeight");
      String imageWidthValue = imageInfoJson.getString("ImageWidth");
      String formatValue = imageInfoJson.getString("Format");
      String fileSizeValue = imageInfoJson.getString("FileSize");
      int imageHeight = JSON.parseObject(imageHeightValue).getIntValue("value");
      int imageWidth = JSON.parseObject(imageWidthValue).getIntValue("value");
      String format = JSON.parseObject(formatValue).getString("value");
      int fileSize = JSON.parseObject(fileSizeValue).getIntValue("value");

      ImageInfo imageInfo1 = new ImageInfo();
      imageInfo1.setImageHeight(imageHeight);
      imageInfo1.setImageWidth(imageWidth);
      imageInfo1.setFileSize(fileSize);
      imageInfo1.setFormat(format);
      return imageInfo1;
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }


}
